﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Google.GData.Calendar;
using Google.GData.Client;
using Google.GData.Extensions;
using System.Globalization;

namespace Obsady
{
    class CGoogleCalendar
    {
        const string kMailsFilename = "..\\..\\data\\mails.mls";
        private List<ILogger> _log;
        string _userName = "wzkosz.leszno";
        string _userPassword = "wzkosz.leszno1";
        string _feedUri = "https://www.google.com/calendar/feeds/default/private/full"; // for working with your primary calendar
        string _calEventsUrl = "https://www.googleapis.com/calendar/v3/calendars/calendarId/events"; // 
        CalendarService service = new CalendarService("exampleCo-exampleApp-1");
       
        Dictionary<string, string> mails = new Dictionary<string, string>(); 

        public CGoogleCalendar(List<ILogger> loggers, string userName, string userPassword)
        {
            _userName = userName;
            _userPassword = userPassword;
            _log = loggers;
            service.setUserCredentials(_userName, _userPassword);
            parseMails(mails);
            _log[0].Log(this,"CGoogleCalendar - constructor");
            _log[0].Log(this, "CGoogleCalendar - username " + _userName);
            _log[0].Log(this, "CGoogleCalendar - userPassword " + _userPassword);

        }

        private void log(string str)
        {
            foreach (ILogger log in _log)
            {
                log.Log(this,str);
            }
        }
        
        public EventEntry CreateEvent(CMatch aMatch)
        {
            DateTime date = new DateTime();
            if (-1 == aMatch._data.IndexOf('.'))
            {
                date = DateTime.FromOADate(double.Parse(aMatch._data));
                log("Tworzenie meczu: " + date.ToShortDateString() + " " + aMatch._godz + " " + aMatch.getContent());
            }
            else
            {
                log("Tworzenie meczu: " + aMatch._data + " " + aMatch._godz + " " + aMatch.getContent());              
            }
                      
            EventEntry entry = new EventEntry();

            // Set the title and content of the entry.
            entry.Title.Text = aMatch.getTitle();
            entry.Content.Content = aMatch.getContent();
            
            // Set a location for the event.
            Where eventLocation = new Where();
            eventLocation.ValueString = aMatch.getLocation();
            entry.Locations.Add(eventLocation);

            // If a recurrence was requested, add it.  Otherwise, set the
            // time (the current date and time) and duration (120 minutes)
            // of the event.
                       
            When eventTime = new When();                        
            eventTime.StartTime = parseDate(aMatch._data,aMatch._godz);
            eventTime.EndTime = eventTime.StartTime.AddHours(2);
            entry.Times.Add(eventTime);

            
            // The indexer throws an exception if the requested key is
            // not in the dictionary.

            foreach (KeyValuePair<string, string> referee in aMatch._referees)
            {
                try
                {
                    Who who = new Who();
                    who.ValueString = mails[referee.Value];
                    who.Rel = "http://schemas.google.com/g/2005#home";
                    entry.Participants.Add(who);
                }
                catch (KeyNotFoundException)
                {
                    if ("-" != referee.Value && "" != referee.Value)
                    {
                        log("nie podano adresu email - " + referee.Value);
                    }
                }
            }

            _log[0].Log(this, "CreateEvent before service.Insert");   
            // Send the request and receive the response:
            AtomEntry insertedEntry = null;
            try
            {
                Uri postUri = new Uri(_feedUri);
                insertedEntry = service.Insert(postUri, entry);
                
            }
            catch (Exception e)
            {
                _log[0].Log(this, e.Message.ToString());
            }
            log("OK!");
            return (EventEntry)insertedEntry;                      
        }

        public void getAllEventsFromCalendar()
        {
            string url = "https://www.google.com/calendar/feeds/wzkosz.leszno@gmail.com/private/full";

            EventQuery myQuery = new EventQuery(url);
            myQuery.StartTime = new DateTime(2011, 12, 1);
            myQuery.EndTime = new DateTime(2011, 12, 2);

            EventFeed myResultsFeed = service.Query(myQuery);
        }

        /// <summary>
        /// Prints the titles of all events matching a full-text query.
        /// </summary>
        /// <param name="service">The authenticated CalendarService object.</param>
        /// <param name="queryString">The text for which to query.</param>
        public void FullTextQuery(CalendarService service, String queryString)
        {
            EventQuery myQuery = new EventQuery(_feedUri);
            myQuery.Query = queryString;

            EventFeed myResultsFeed = service.Query(myQuery) as EventFeed;

            Console.WriteLine("Events matching \"{0}\":", queryString);
            Console.WriteLine();

            for (int i = 0; i < myResultsFeed.Entries.Count; i++)
            {
                Console.WriteLine(myResultsFeed.Entries[i].Title.Text);
            }
            Console.WriteLine();
        }

        private DateTime parseDate(string aDate,string aTime)
        {            
            _log[0].Log(this, "parseDate - started ");
            DateTime date = new DateTime();
            try
            {
                date = parseDate(aDate, aTime, date);
            }
            catch (Exception e)
            {
                log("Zły format daty. Data = " + date.ToShortDateString());                
            }
            _log[0].Log(this, "parseDate  - end");
            return date;            
        }

        private static DateTime parseDate(string aDate, string aTime, DateTime date)
        {
            if (-1 != aDate.IndexOf('.')) {
                date = extractDataFromString(aDate, aTime, date);
            } else {
                date = extractDataFromOADate(aDate, aTime, date);
            }
            return date;
        }

        private static DateTime extractDataFromOADate(string aDate, string aTime, DateTime date)
        {
            date = DateTime.FromOADate(double.Parse(aDate));
            aTime = aTime.Replace(",", ".");
            double d = double.Parse(aTime, CultureInfo.InvariantCulture);
            DateTime time = DateTime.FromOADate(d);            
            date = date.AddHours(time.Hour);
            date = date.AddMinutes(time.Minute);
            return date;
        }

        private static DateTime extractDataFromString(string aDate, string aTime, DateTime date)
        {
            int day = ExtractPartOfDateOrTime(aDate, 0, 2);
            int month = ExtractPartOfDateOrTime(aDate, 3, 2);
            int year = ExtractPartOfDateOrTime(aDate, 6, 4);
            int hour = ExtractPartOfDateOrTime(aTime, 0, 2);
            int min = ExtractPartOfDateOrTime(aTime, 0, 2);
            date = date.AddDays(day - 1).AddMonths(month - 1).AddMinutes(min).AddHours(hour).AddYears(year - 1);
            return date;
        }

        private static int ExtractPartOfDateOrTime(string aDateOrTime, int start, int end)
        {
            int part = int.Parse(aDateOrTime.Substring(start, end));
            return part;
        }

        private void parseMails(Dictionary<string, string> aMails)
        {
            log("Parsowanie maili...");  
            StreamReader streamReader = new StreamReader(kMailsFilename, Encoding.Default);
            string str = streamReader.ReadLine();
            while ((str = streamReader.ReadLine()) != null)
            {
                int pos = 0;
                int last = 0;
                pos = str.IndexOf("|", 0);
                if (pos != -1)
                {   // Nazwisko
                    String surname = str.Substring(last, pos - last);
                    last = pos++;
                    pos = str.IndexOf("|", pos);
                    last++; // +1 skip separator
                        if (-1 != pos)
                        {   // e-mail
                            String email = str.Substring(last, pos - last); // +1 skip separator
                            surname = surname.Trim();
                            email = email.Trim();
                            try
                            {
                                aMails.Add(surname, email);
                            }
                            catch (System.ArgumentException ex)
                            {
                                if (surname != "")
                                {
                                    log("Takie nazwisko już jest w bazie " + surname);                                   
                                }
                            }
                        }
                    }                    
            }
            streamReader.Close();
            log("Parsowanie ukończone");
        }
    }
}
